# -*- coding:utf-8 -*-
from django.shortcuts import render_to_response, resolve_url
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth import authenticate, login, logout, decorators
from functools import wraps

import utils
import json
import config
import datetime

import models.base.models as wc_models
import models.epgsync.models as epg_models
import models.action.models as ac_models

from wanbatvcom.http.decorators import require_params
from wanbatvcom.http.result_code import ResultCode
from wanbatvcom.http.whttp import send_response_with_result, send_ok_response_with_data, send_error_response_with_message

LOGIN_URL = '/login'

from django.core.urlresolvers import reverse

from wanbatvcom.http.decorators import check_login, require_params
from wancake.view.render import DashboardRender
from wancake.resmng.models import Member

def _render(view_name, request, context=None):
    session_id = request.GET["session"]
    render = DashboardRender(view_name, session_id=session_id)
    return render.render(request, context=context)

def doauth(request):
    """
    进入平台时先验证平台是否已经完成初始化的操作，如果没有初始化，则进入安装页面
    否则，进入登录页面
    :param request:
    :return:
    """

    # 从配置项中获取初始化标记
    initedFlag = wc_models.Settings.objects.get_or_create(name='inited', defaults={'name': 'inited', 'value': 'False'})

    if initedFlag == 'True':    # 已经初始化
        page = 'login.html'
    else:
        page = 'install.html'

    return render_to_response(config.BASE_PATH + page)

@check_login()
def index(request):
    """
    首页
    :param request:
    :return:
    """
    session_id = request.GET["session"]
    try:
        member = Member.objects.get(session_id=session_id)
        if member.group_id == 31:
            return HttpResponseRedirect("%s?session=%s" % (reverse(product_details), session_id))

    except Member.DoesNotExist:
        pass
    return _render("index.html", request)

def login(request):
    """
    登录页面
    :param request:
    :return:
    """
    return render_to_response(config.BASE_PATH + "login.html", {})

def dologin(request):
    """
    执行登录操作
    :param request:
    :return:
    """
    arguments = request.GET
    username = arguments["un"]
    password = arguments["pw"]

    user = authenticate(username=username, password=password)
    res = dict()
    if user is not None:
        user_model = wc_models.User.objects.filter(username=username)
        if user_model is None:
            user_model = wc_models.User()
            user_model.username = user.username
            user_model.password = user.password
            user_model.save()

        if user.is_active:
            login(user)
            res["resultCode"] = 1
            res["message"] = ""

        else:
            res["resultCode"] = 2
            res["message"] = u'The password is valid, but the account has been disabled'

    else:
        res["resultCode"] = 0
        res["message"] = u'The username and password were incorrect'

    return HttpResponse(json.dumps(res), content_type="application/json")

def dologout(request):
    logout(request)
    res = {
        "resultCode": 1,
        "message": ""
    }

    return HttpResponse(json.dumps(res), content_type="application/json")

@check_login()
def product_details(request):
    """
    处理产品详情页面
    :param request:
    :return:
    """
    return _render("product_details.html", request, context={"session_id": request.GET["session"]})

@check_login()
def order_record(request):
    """
    处理订购记录页面
    :param request:
    :return:
    """
    return _render("order_record.html", request, context={"session_id": request.GET["session"]})

def user_list(request):
    """
    处理用户列表页面
    :param request:
    :return:
    """
    return render_to_response(config.BASE_PATH + "user_list.html", {})

def get_res_mng_index(request):
    """
    处理资源管理页面
    :param request:
    :return:
    """
    return render_to_response(config.BASE_PATH + "res_mng_index.html", {})


def get_index_business_data(request):
    """
    获取首页业务总体数据
    :param request:
    :return:
    """
    query = request.GET
    page_size = 20
    if "pagesize" in query:
        page_size = int(query["pagesize"])
    if page_size < 0:
        page_size = 20

    page_number = 0
    if "pagenum" in query:
        page_number = int(query["pagenum"]) - 1
    if page_number < 0:
        page_number = 0

    current_index = page_number * page_size
    qs = epg_models.EpgWanbaDailyStatis.objects.order_by("-id").values(
        "epg_id", "daily_date", "pv_count", "sd_pv_count", "stb_count", "sd_stb_count",
        "new_users", "sd_new_users", "wanba_pack_order_num", "sd_wanba_pack_order_num",
        "dog_bar_num", "sd_dog_bar_num", "dog_tv_num", "sd_dog_tv_num",
        "other_pack_order_num", "sd_other_pack_order_num").distinct()
    result = qs[current_index: current_index + page_size]
    length = qs.count()
    res = dict()
    if length > 0:

        res["resultCode"] = 1
        res["message"] = u''
        data = dict()
        res["data"] = data
        query_set = list()
        data["list"] = query_set
        data["totalPage"] = length
        data["currentPage"] = page_number

        last_id = 0

        for order_business_statis_item in result:
            # query_set.append(order_business_statis_item.to_json())
            o = {}
            item_datetime = order_business_statis_item["daily_date"]
            # from datetime import timedelta
            # hours_delta = timedelta(hours=8)
            # item_datetime += hours_delta
            o["datetime"] = item_datetime.strftime("%Y-%m-%d")
            o["pv_hd"] = order_business_statis_item["pv_count"]
            o["pv_sd"] = order_business_statis_item["sd_pv_count"]
            o["users_hd"] = order_business_statis_item["stb_count"]
            o["users_sd"] = order_business_statis_item["sd_stb_count"]
            o["new_series_hd"] = order_business_statis_item["new_users"]
            o["new_series_sd"] = order_business_statis_item["sd_new_users"]
            o["wanba_hd"] = order_business_statis_item["wanba_pack_order_num"]
            o["wanba_sd"] = order_business_statis_item["sd_wanba_pack_order_num"]
            o["happydog_hd"] = order_business_statis_item["dog_bar_num"]
            o["happydog_sd"] = order_business_statis_item["sd_dog_bar_num"]
            o["dogtv_hd"] = order_business_statis_item["dog_tv_num"]
            o["dogtv_sd"] = order_business_statis_item["sd_dog_tv_num"]
            o["other_hd"] = order_business_statis_item["other_pack_order_num"]
            o["other_sd"] = order_business_statis_item["sd_other_pack_order_num"]

            last_id = order_business_statis_item["epg_id"]

            query_set.append(o)

        data["lastId"] = last_id

    else:
        res["resultCode"] = 2
        res["message"] = u'数据为空'

    return HttpResponse(json.dumps(res), content_type="application/json;charset=utf-8")

def get_index_30day_pv(request):

    query_result = epg_models.EpgWanbaDailyStatis.objects.order_by("-id")
    length = len(query_result)
    res = dict()
    if length > 0:
        res["resultCode"] = 1
        res["message"] = u''
        data = dict()
        res["data"] = data
        query_set = list()
        data["list"] = query_set

        i = 0
        for order_business_statis_item in query_result:
            i += 1
            # query_set.append(order_business_statis_item.to_json())
            o = dict()
            o["datetime"] = order_business_statis_item.daily_date.strftime("%Y-%m-%d")
            o["pv_hd"] = order_business_statis_item.pv_count
            o["pv_sd"] = order_business_statis_item.sd_pv_count
            query_set.append(o)

            if i >= 30:
                break

    else:
        res["resultCode"] = 2
        res["message"] = u'数据为空'

    return HttpResponse(json.dumps(res), content_type="application/json;charset=utf-8")

def get_digest(request):
    result = wc_models.Digest.objects.all()[0]
    res = dict()
    if result is not None:
        res["resultCode"] = 1
        res["message"] = u''

        data = result.to_json()
        data["orders"] = utils.format_value(data["orders"])
        data["users"] = utils.format_value(data["users"])
        data["pv"] = utils.format_value(data["pv"])
        data["contents"] = utils.format_value(data["contents"])
        data["durations"] = utils.format_value(data["durations"] / 3600)
        res["data"] = data

    else:
        res["resultCode"] = 0
        res["message"] = u''

    return HttpResponse(json.dumps(res), content_type="application/json;charset=utf-8")

@require_params(["session"], method="GET")
def get_order_history(request):
    query = request.GET

    page_size = 20
    if "pagesize" in query:
        page_size = int(query["pagesize"])
    if page_size < 0:
        page_size = 20

    page_number = 0
    if "pagenum" in query:
        page_number = int(query["pagenum"]) - 1
    if page_number < 0:
        page_number = 0

    session_id = query["session"]
    try:
        member = Member.objects.get(session_id=session_id)
        own_product = member.rule.own_product
        if own_product == "*":
            own_products = own_product
        else:
            own_products = own_product.split("|")
    except Member.DoesNotExist:
        return send_error_response_with_message(message=u'用户 %s 无权限' % session_id)

    current_index = page_number * page_size
    if isinstance(own_products, list):
        qs = epg_models.EpgOrderRecord.objects.filter(product_id__in=own_products).order_by('-id')
    elif own_products == "*":
        qs = epg_models.EpgOrderRecord.objects.order_by('-id')
    else:
        return send_error_response_with_message(message=u'用户 %s 无权限' % session_id)

    count = qs.count()
    result = qs[current_index: current_index + page_size]
    res = dict()
    if result is not None:
        res["resultCode"] = 1
        res["message"] = u''
        list_data = list()
        # for item in result:
        #     list_data.append(item.to_json())
        last_index = 0
        for item in result:
            o = dict()
            o["user_id"] = item.user_id
            o["user_bid"] = item.user_id
            o["product_name"] = item.product_name
            o["date_added"] = item.subscribe_time.strftime('%Y-%m-%d %H:%M:%S') if item.subscribe_time else ""
            if not item.unsubscribe_time or item.unsubscribe_time > datetime.datetime.now():
                o["date_off"] = ""
            else:
                o["date_off"] = item.unsubscribe_time.strftime('%Y-%m-%d %H:%M:%S')
            o["state"] = 1 if o["date_off"] else 0
            o["platform"] = 1 if item.sd_or_hd == 'hd' else 2

            list_data.append(o)
            last_index = item.epg_id

        res["data"] = dict()
        res["data"]["list"] = list_data
        res["data"]["lastIndex"] = last_index
        res["data"]["currentPage"] = page_number + 1
        res["data"]["totalPage"] = count / page_size if count % page_size == 0 else count / page_size + 1

    else:
        res["resultCode"] = 2
        res["message"] = u'数据为空'

    return HttpResponse(json.dumps(res), content_type="application/json;charset=utf-8")

@check_login()
def epg_syncer(request):
    return _render("epg_syncer.html", request)

def get_epg_sync_record(request):
    query = request.GET
    table_name = query['table']
    sync_records = epg_models.EpgSyncRecord.objects.filter(table_name=table_name)
    sync_record = sync_records[0] if len(sync_records) > 0 else None
    res = dict()
    res["resultCode"] = 0
    res["message"] = u''
    data = dict()
    res["data"] = data
    if sync_record is not None:
        data["last_id"] = sync_record.last_id
    else:
        data["last_id"] = 0

    return HttpResponse(json.dumps(res), content_type="application/json;charset=utf-8")


def save_epg_tables(request):
    """
    将远程epg数据保存到本地的epg表中
    :param request:
    :return:
    """
    query = request.POST
    # epg表名
    table_name = query['table']
    # 远程epg数据的主键字段名称，默认id，如果请求参数中有rawIdColumnName，
    # 则用rawIdColumnName的值覆盖默认值
    raw_id_col_name = 'id'
    if 'rawIdColumnName' in query.keys():
        raw_id_col_name = query["rawIdColumnName"]
    # data是json结构的字符串
    data_str = query['epgData']
    data = json.loads(data_str)
    length = len(data)
    i = 0

    if length > 0:
        # 根据请求参数中指定的表名动态导入Epg的model对象
        last_id = -1
        module = __import__('wancake.models.epgsync.models', {}, {}, ['models'])
        for item in data:
            try:
                model = getattr(module, table_name)()
                model.from_json(item, epg_id_column_name=raw_id_col_name)
                model.save()
                last_id = item[raw_id_col_name]
                i += 1
            except Exception, e:
                print(e)
                raise e

        # 跟新同步记录，用于下次同步是做比较，只更新最新变动的数据
        (sync_record_model, create) = epg_models.EpgSyncRecord.objects.update_or_create(table_name=table_name, defaults=None)
        sync_record_model.last_id = last_id
        sync_record_model.column_name = raw_id_col_name
        if create:
            sync_record_model.table_name = table_name
        sync_record_model.sync_datetime = datetime.datetime.now()

        sync_record_model.save()

    res = dict()
    if i == length:
        res["resultCode"] = ResultCode.OK
        res["message"] = u''
    else:
        res["resultCode"] = ResultCode.ERROR
        res["message"] = u''

    return HttpResponse(json.dumps(res), content_type="application/json;charset=utf-8")


def clear_epg_tables(request):
    """
    清空epg表数据
    :param request:
    :return:
    """
    query = request.GET
    if "table" not in query.keys():
        return send_response_with_result(json.dumps({
            "resultCode": 0,
            "message": u'缺少必要参数:table'
        }))

    table_name = query["table"]
    module = __import__('wancake.models.epgsync.models', {}, {}, ['models'])

    if not hasattr(module, table_name):
        return send_response_with_result(json.dumps({
            "resultCode": 0,
            "message": u'不存在模块%s' % table_name
        }))

    # 清空表数据
    model_class = getattr(module, table_name)
    model_class.objects.all().delete()
    # 更新同步记录表，将last_id重置为0
    (sync_record_model, create) = epg_models.EpgSyncRecord.objects\
        .update_or_create(table_name=table_name, defaults=None)
    sync_record_model.last_id = 0
    if create:
        sync_record_model.table_name = table_name
    sync_record_model.sync_datetime = datetime.datetime.now()
    sync_record_model.save()

    print u'[%s] clear table %s' % (datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), table_name)

    return send_response_with_result(json.dumps({
            "resultCode": 0,
            "message": u'',
            "data": {
                "model": table_name
            }
        }))

@require_params(["session"])
def get_product_details_data(request):

    session_id = request.GET["session"]
    try:
        member = Member.objects.get(session_id=session_id)
        own_product = member.rule.own_product
        if own_product == '*':
            own_products = own_product
        else:
            own_products = own_product.split("|")

    except Member.DoesNotExist:
        return send_error_response_with_message(message=u'用户 %s 无权限' % session_id)

    def _init_with_name(name):
        item = dict()
        item["cate_name"] = name
        item["pv_hd"] = 0
        item["pv_sd"] = 0
        item["users_hd"] = 0
        item["users_sd"] = 0
        item["orders_sd"] = 0
        item["orders_hd"] = 0
        item["content_list_hd"] = []
        item["content_list_sd"] = []
        item["content_count_hd"] = 0
        item["content_count_sd"] = 0
        item["durations_hd"] = 0
        item["durations_sd"] = 0
        item["play_count_hd"] = 0
        item["play_count_sd"] = 0
        item["week_active_hd"] = 0
        item["week_active_sd"] = 0
        item["today_active_hd"] = 0
        item["today_active_sd"] = 0

        return item

    product_details_list = epg_models.EpgStatisCategory.objects.all()
    product_details_data = dict()
    if product_details_list.exists():
        now = datetime.datetime.now()
        for product_item_data in product_details_list.iterator():
            cate_code = product_item_data.cate_code

            if cate_code in product_details_data:
                pd = product_details_data[cate_code]
            else:

                filter_kwargs = {
                    "cate_code": cate_code
                }
                if own_products and isinstance(own_products, list):
                    filter_kwargs["product_code__in"] = own_products

                products = wc_models.WanbaProductCategory.objects.filter(**filter_kwargs)
                product_ids = list()
                for product in products:
                    product_ids.append(product.product_code)

                if len(product_ids) == 0:
                    continue

                pd = _init_with_name(product_item_data.cate_name)
                order_sd_record = epg_models.EpgOrderRecord.objects.filter(product_id__in=product_ids, sd_or_hd='sd')
                order_hd_record = epg_models.EpgOrderRecord.objects.filter(product_id__in=product_ids, sd_or_hd='hd')
                pd["orders_sd"] = order_sd_record.count()
                pd["orders_hd"] = order_hd_record.count()

                product_details_data[cate_code] = pd

            play_date = product_item_data.play_date
            days_delta = (now - play_date).days
            if days_delta == 0:
                pd["today_active_" + platform] += 1
            if days_delta < 8:
                pd["week_active_" + platform] += 1

            platform = product_item_data.sd_or_hd
            pd["pv_" + platform] = pd["pv_" + platform] + product_item_data.pv_count
            pd["users_" + platform] = pd["users_" + platform] + product_item_data.stb_count
            content_code = product_item_data.content_code
            if content_code not in pd["content_list_" + platform]:
                pd["content_count_" + platform] += 1
                pd["content_list_" + platform].append(content_code)

            pd["durations_" + platform] += product_item_data.seconds
            pd["play_count_" + platform] += product_item_data.pv_valid_count

    result_data_list = []
    for value in product_details_data.values():
        del value["content_list_hd"]
        del value["content_list_sd"]
        value["durations_hd"] = utils.format_value(value["durations_hd"], 3600.0, 'h')
        value["durations_sd"] = utils.format_value(value["durations_sd"], 3600.0, 'h')
        result_data_list.append(value)

    dogtv = _init_with_name("Dog TV")
    if '1000706526' in own_products or own_products == '*':
        result_data_list.append(dogtv)

    happdog = _init_with_name("Happy Dog")
    if own_products == '*':
        result_data_list.append(happdog)

    dog_product_codes = list()
    if dogtv in result_data_list:
        dog_product_codes.append("1000706526")
    if happdog in result_data_list:
        dog_product_codes.append("1000706466")

    if len(dog_product_codes) > 0:
        dog_product_cates = dict()
        qs = wc_models.WanbaProductCategory.objects.values("product_code", "cate_code")\
            .filter(product_code__in=dog_product_codes)
        try:
            for qs_item in qs:
                pc = qs_item["product_code"]
                if pc not in dog_product_cates.keys():
                    dog_product_cates[pc] = list()
                dog_product_cates[pc].append(qs_item["cate_code"])
        except Exception as e:
            pass

        if len(dog_product_cates.keys()) > 0:
            filter_list = list()
            for key in dog_product_cates.keys():
                for category in dog_product_cates[key]:
                    filter_list.append(category)
            play_qs = epg_models.EpgUserPlayDetail.objects.filter(cate_code__in=filter_list)
            try:
                temp_user_list = list()
                for play_item in play_qs:
                    if play_item.cate_code in dog_product_cates["1000706526"]:
                        if play_item.sd_or_hd == 'sd':
                            dogtv["pv_sd"] += 1
                            dogtv["play_count_sd"] += 1
                            if play_item.user_id not in temp_user_list:
                                dogtv["users_sd"] += 1
                        else:
                            dogtv["pv_hd"] += 1
                            dogtv["play_count_hd"] += 1
                            if play_item.user_id not in temp_user_list:
                                dogtv["users_hd"] += 1

                    elif play_item.cate_code in dog_product_cates["1000706466"]:
                        if play_item.sd_or_hd == 'sd':
                            happdog["pv_sd"] += 1
                            happdog["play_count_sd"] += 1
                            if play_item.user_id not in temp_user_list:
                                happdog["users_sd"] += 1
                        else:
                            happdog["pv_hd"] += 1
                            happdog["play_count_hd"] += 1
                            if play_item.user_id not in temp_user_list:
                                happdog["users_hd"] += 1

                    temp_user_list.append(play_item.user_id)

            except Exception as e:
                return send_error_response_with_message(message=e.message)

    wanba = _init_with_name("玩吧包月")
    if own_products == '*':
        result_data_list.append(wanba)

    daily_statis_list = epg_models.EpgWanbaDailyStatis.objects.all()
    if daily_statis_list.exists():
        for daily_statis_item in daily_statis_list:
            if dogtv in result_data_list:
                dogtv["orders_sd"] += daily_statis_item.sd_dog_tv_num
                dogtv["orders_hd"] += daily_statis_item.dog_tv_num

            if happdog in result_data_list:
                happdog["orders_sd"] += daily_statis_item.sd_dog_bar_num
                happdog["orders_hd"] += daily_statis_item.dog_bar_num

            if wanba in result_data_list:
                wanba["orders_sd"] += daily_statis_item.sd_wanba_pack_order_num
                wanba["orders_hd"] += daily_statis_item.wanba_pack_order_num

    if own_products == '*':
        action_page_list = ac_models.ActionPageRecord.objects.filter(flavor='anhui', action_code=1000003).all()
        if action_page_list.exists():

            ah_wanba = _init_with_name("安徽玩吧")

            result_data_list.append(ah_wanba)
            ah_wanba["pv_hd"] = action_page_list.count()

            stb_user_list = wc_models.StbUser.objects.filter(flavor='anhui').all()
            ah_wanba["users_hd"] = stb_user_list.count() if stb_user_list.exists() else 0

    res = dict()
    res["resultCode"] = 1
    res["message"] = u''
    res["data"] = {"list": result_data_list}

    return HttpResponse(json.dumps(res), content_type="application/json;charset=utf-8")

def gen_app_key(request):
    query = request.GET
    app_name = query["an"]
    app_pkg = query["pkg"]
    qs = wc_models.ApplicationInfo.objects.all()
    length = qs.count()
    app_code = "W{}".format(str(length + 1).zfill(5))
    now = datetime.datetime.now()
    import time
    app_key = utils.generate_appkey(app_code, app_name.encode("utf-8"), app_pkg, long(time.mktime(now.timetuple())))

    model = wc_models.ApplicationInfo()
    model.app_key = app_key
    model.name = app_name
    model.code = app_code
    model.package = app_pkg
    model.date_added = now
    model.save()

    res = {
        "resultCode": 1,
        "message": u'',
        "data": {
            "appname": app_name,
            "appcode": app_code,
            "appkey": app_key,
            "date_added": now.strftime("%Y-%m-%d %H:%M:%S")
        }
    }

    return HttpResponse(json.dumps(res), content_type="application/json;charset=utf-8")

def relate_product_with_category(request):
    query = request.GET
    product_code = query["pc"]
    category_code = query["cc"]

    try:
        obj = wc_models.WanbaProductCategory.objects.get(product_code=product_code, cate_code=category_code)
    except wc_models.WanbaProductCategory.DoesNotExist:
        obj = wc_models.WanbaProductCategory()
        obj.product_code = product_code
        obj.cate_code = category_code
        obj.save()

    return send_ok_response_with_data({
        "relate": True
    })


def epg_order_record_info(request):

    from wancake.models.epgsync.models import EpgOrderRecord
    record_infos = list()
    record_infos.append(["产品名称", "总共", "退订", "在订"])
    total_info = {
        "name": "总计",
        "total": 0,
        "unsubscribed": 0,
        "subscribing": 0
    }
    temp = dict()
    record_qs = EpgOrderRecord.objects.all()
    for record_item in record_qs:
        pid = record_item.product_id
        if pid not in temp.keys():
            name = record_item.product_name
            if pid == '1000706466':
                name = u'快乐汪星人'
            elif pid == '1000706526':
                name = u'Dog TV'
            temp[pid] = {
                "name": name,
                "total": 0,
                "unsubscribed": 0,
                "subscribing": 0
            }

        temp[pid]["total"] += 1
        total_info["total"] += 1
        now = datetime.datetime.now()
        if record_item.unsubscribe_time and record_item.unsubscribe_time < now:
            temp[pid]["unsubscribed"] += 1
            total_info["unsubscribed"] += 1
        else:
            temp[pid]["subscribing"] += 1
            total_info["subscribing"] += 1

    for key, value in enumerate(temp):
        val = temp[value]
        record_infos.append([val["name"].encode("utf8"), val["total"], val["unsubscribed"], val["subscribing"]])

    record_infos.append([total_info["name"], total_info["total"],
                         total_info["unsubscribed"], total_info["subscribing"]])

    import csv
    import codecs
    response = HttpResponse(content_type="text/csv;charset=utf-8")
    response.write(codecs.BOM_UTF8)
    wrt = csv.writer(response, dialect='excel')
    for item in record_infos:
        wrt.writerow(item)

    response["Content-Disposition"] = "attachment;filename=OrderInfo.csv"

    return response
